package com.ym.medical.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ym.base.enums.FlagEnum;
import com.ym.common.constant.DictEnum;
import com.ym.core.exception.BusinessException;
import com.ym.core.utils.tkmybatis.BaseSVImpl;
import com.ym.medical.dao.StudioRelatedFormDao;
import com.ym.medical.domain.bo.PushBean;
import com.ym.medical.domain.bo.PushBeanExtraVo;
import com.ym.medical.domain.entity.DoctorStudioEntity;
import com.ym.medical.domain.entity.DoctorStudioPricingEntity;
import com.ym.medical.domain.entity.InformationEntity;
import com.ym.medical.domain.entity.StudioPersonServiceEntity;
import com.ym.medical.domain.entity.StudioPersonnelEntity;
import com.ym.medical.domain.entity.StudioRelatedFormEntity;
import com.ym.medical.domain.param.StudioRelatedFormUpdateParam;
import com.ym.medical.domain.vo.StudioRelatedFormVo;
import com.ym.medical.enums.JoinStudioAppStatusEnum;
import com.ym.medical.enums.JoinStudioServAppStatusEnum;
import com.ym.medical.enums.JoinStudioServTypeEnum;
import com.ym.medical.enums.JoinStudioTypeEnum;
import com.ym.medical.enums.StudioPersonnelRelEnum;
import com.ym.medical.service.IDoctorStudioPricingSV;
import com.ym.medical.service.IDoctorStudioSV;
import com.ym.medical.service.IInformationSV;
import com.ym.medical.service.IJpushAccountSV;
import com.ym.medical.service.IStudioPersonServiceSV;
import com.ym.medical.service.IStudioPersonnelSV;
import com.ym.medical.service.IStudioRelatedFormSV;
import com.ym.medical.service.IUserSV;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 工作室相关申请表Service业务层处理
 *
 * @author ym
 * @date 2020-09-14
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class StudioRelatedFormSVImpl extends BaseSVImpl<StudioRelatedFormEntity, StudioRelatedFormDao> implements IStudioRelatedFormSV {

	@Autowired
	private IDoctorStudioPricingSV doctorStudioPricingSV;

	@Autowired
	private IStudioPersonnelSV studioPersonnelSV;

	@Autowired
	private IStudioPersonServiceSV studioPersonServiceSV;

	@Autowired
	private IDoctorStudioSV doctorStudioSV;

	@Autowired
	private IUserSV userSV;

	@Autowired
	private IJpushAccountSV jpushAccountSV;

	@Autowired
	private IInformationSV informationSV;

	/**
	 * 新增工作室相关申请表
	 *
	 * @param updateParam 工作室相关申请表 新增参数
	 * @return 结果
	 */
	@Override
	public Long insertPC(StudioRelatedFormUpdateParam updateParam) {
		StudioRelatedFormEntity entity = updateParam.covert();
		this.insert(entity);
		return entity.getId();
	}

	/**
	 * 修改工作室相关申请表
	 *
	 * @param updateParam 工作室相关申请表 修改参数
	 * @return 结果
	 */
	@Override
	public int updateByIdPC(StudioRelatedFormUpdateParam updateParam) {
		StudioRelatedFormEntity entity = updateParam.covert("createTime");
		int result = this.updateById(entity);
		return result;
	}

	@Override
	public StudioRelatedFormVo queryJoinStudioAppServ(Long id) {
		StudioRelatedFormVo studioRelatedFormVo = mapper.queryJoinStudioAppServ(id);
		// 服务项详情设置
		List<DoctorStudioPricingEntity> doctorStudioPricings = doctorStudioPricingSV.queryDoctorStudioPricing(Long.valueOf(studioRelatedFormVo.getDsDoctorId()), false);
		String serviceItem = studioRelatedFormVo.getServiceItem();
		if (StringUtils.isNotBlank(serviceItem)) {
			String[] split = serviceItem.split(",");
			doctorStudioPricings = doctorStudioPricings.stream()
					.filter(n -> Arrays.binarySearch(split, n.getServiceId()) > -1)
					.collect(Collectors.toList());
		}
		studioRelatedFormVo.setServiceDetail(doctorStudioPricings);
		return studioRelatedFormVo;
	}


	/**
	 * 验证数据有效性
	 *
	 * @param studioRelatedForm 申请表单
	 * @param doctId            医生id
	 */
	private void verifyTheData(StudioRelatedFormEntity studioRelatedForm, Long doctId) {
		// 申请前,查询是否已经是工作室人员
		if (studioRelatedForm.getAlreadyJoined().equals(FlagEnum.NO.getKey())) {
			int count = studioPersonnelSV.countByParams(StudioPersonnelEntity.builder().dsId(studioRelatedForm.getStudioId()).doctId(doctId).build());
			if (count > 0) {
				throw new BusinessException("已经是工作室成员");
			}
		} else {
			// 查询是否已经开通服务项
			String serviceItem = studioRelatedForm.getServiceItem();
			if (StringUtils.isNotBlank(serviceItem)) {
				String[] split = serviceItem.split(",");
				for (String item : split) {
					StudioPersonnelEntity single = studioPersonnelSV.selectOne(StudioPersonnelEntity.builder().dsId(studioRelatedForm.getStudioId()).doctId(doctId).build());
					int count = studioPersonServiceSV.countByParams(StudioPersonServiceEntity.builder().studioPersonId(single.getId()).serviceId(item).build());
					if (count > 0) {
						throw new BusinessException("请勿重复开通服务项!");
					}
				}
			}
		}
	}


	@Override
	public void applyToJoinTheStudio(StudioRelatedFormEntity studioRelatedForm, Long doctId) {
		verifyTheData(studioRelatedForm, doctId);
		DoctorStudioEntity doctorStudio = doctorStudioSV.selectById(studioRelatedForm.getStudioId());
		boolean joinStudio = false;
		boolean apply = false;
		if (studioRelatedForm.getAlreadyJoined().equals(FlagEnum.NO.getKey())) {
			// 加入工作室
			joinStudio = true;
		} else {
			//开通服务项
			joinStudio = false;
		}
		if (JoinStudioServTypeEnum.TO_APPLY_FOR.getKey().equals(studioRelatedForm.getJoinType())) {
			// 申请
			apply = true;
		} else {
			// 邀请
			apply = false;
		}
		String msgTypeSub = null;
		Long pushWhoId = null;
		Long whoPushId = null;
		if (apply) {
			// 如果是申请
			msgTypeSub = joinStudio ? "02" : "03";
			pushWhoId = doctorStudio.getBelongPerson();
			whoPushId = doctId;
		}
		if (!apply) {
			//如果是邀请
			msgTypeSub = joinStudio ? "05" : "06";
			pushWhoId = doctId;
			whoPushId = doctorStudio.getBelongPerson();
		}
		studioRelatedForm.setDoctorId(doctId);
		studioRelatedForm.setState(JoinStudioServAppStatusEnum.TO_AUDIT.getKey());
		this.insert(studioRelatedForm);
		PushBean pushBean = new PushBean();
		pushBean.setAlert("工作室来新消息了");
		PushBeanExtraVo pushBeanExtra = new PushBeanExtraVo();
		pushBeanExtra.setBusinessId(studioRelatedForm.getId().toString());
		pushBeanExtra.setContent(null);
		pushBeanExtra.setMsgTypeParent("02");
		pushBeanExtra.setStatus("01");
		pushBeanExtra.setMsgTypeSub(msgTypeSub);
		pushBeanExtra.setWhoPush(userSV.selectById(whoPushId));
		pushBeanExtra.setPushWho(userSV.selectById(pushWhoId));
		pushBeanExtra.setTime(DateUtil.now());
		pushBean.setExtras(pushBeanExtra);
		jpushAccountSV.pushMessage(pushBean, true);
	}

	@Override
	public void checkJoinStudioServApp(Long id, Long informationId, String checkState, String sign, String reviewOpinion) {
		JoinStudioAppStatusEnum values = DictEnum.valueOfEnum(JoinStudioAppStatusEnum.class, checkState);
		StudioRelatedFormEntity servApp = this.selectById(id);
		DoctorStudioEntity doctorStudio = doctorStudioSV.selectById(servApp.getStudioId());
		// 审核通过前,查询是否已经是工作室人员
		verifyTheData(servApp, servApp.getDoctorId());
		// 审核步骤
		servApp.setState(checkState);
		servApp.setReviewOpinion(reviewOpinion);
		JoinStudioTypeEnum enumByCode = DictEnum.valueOfEnum(JoinStudioTypeEnum.class, servApp.getJoinType());
		Long pushWhoId = null;
		Long whoPushId = null;
		switch (enumByCode) {
			case BE_INVITED:
				servApp.setPartbSign(sign);
				pushWhoId = doctorStudio.getBelongPerson();
				whoPushId = servApp.getDoctorId();
				break;
			case TO_APPLY_FOR:
				whoPushId = doctorStudio.getBelongPerson();
				pushWhoId = servApp.getDoctorId();
				servApp.setPartaSign(sign);
				break;
		}
		this.updateById(servApp);
		boolean pass = false;
		if (JoinStudioAppStatusEnum.HAVE_BEEN_THROUGH == values) {
			pass = true;
			handleThrough(servApp, doctorStudio, checkState, reviewOpinion);
		}
		// 更新历史的消息记录的审核状态
		InformationEntity information = informationSV.selectById(informationId);
		String extContent = information.getExtContent();
		PushBeanExtraVo pushBeanExtraVo = JSONObject.parseObject(extContent, PushBeanExtraVo.class);
		pushBeanExtraVo.setStatus(pass ? "03" : "02");
		information.setExtContent(JSONObject.toJSONString(pushBeanExtraVo));
		informationSV.updateById(information);
		// 发推送消息
		PushBean pushBean = new PushBean();
		pushBean.setAlert("工作室来新消息了！");
		PushBeanExtraVo pushBeanExtra = new PushBeanExtraVo();
		pushBeanExtra.setBusinessId(servApp.getId().toString());
		pushBeanExtra.setContent(servApp.getReviewOpinion());
		pushBeanExtra.setMsgTypeParent("02");
		pushBeanExtra.setMsgTypeSub(enumByCode == JoinStudioTypeEnum.TO_APPLY_FOR ? "01" : "07");
		pushBeanExtra.setStatus(pass ? "03" : "02");
		pushBeanExtra.setWhoPush(userSV.selectById(whoPushId));
		pushBeanExtra.setPushWho(userSV.selectById(pushWhoId));
		pushBeanExtra.setTime(DateUtil.now());
		pushBean.setExtras(pushBeanExtra);
		jpushAccountSV.pushMessage(pushBean, true);
	}

	/**
	 * 通过申请
	 *
	 * @param servApp       申请表单
	 * @param doctorStudio  工作室
	 * @param checkState    拒绝状态
	 * @param reviewOpinion 拒绝意见
	 * @return
	 */
	private void handleThrough(StudioRelatedFormEntity servApp, DoctorStudioEntity doctorStudio, String checkState, String reviewOpinion) {
		StudioPersonnelEntity personnel = new StudioPersonnelEntity();
		// 加入工作室
		if (servApp.getAlreadyJoined().equals(FlagEnum.IS.getKey())) {
			// 表示是申请开通服务项
			personnel = studioPersonnelSV.selectOne(StudioPersonnelEntity.builder().dsId(servApp.getStudioId()).doctId(servApp.getDoctorId()).build());
		} else {
			// 表示是加入工作室的申请
			personnel.setDsId(servApp.getStudioId());
			personnel.setDoctId(servApp.getDoctorId());
			personnel.setAdmsStateDoctor(FlagEnum.IS.getKey());
			personnel.setAdmsStateStudio(FlagEnum.IS.getKey());
			personnel.setRelType(StudioPersonnelRelEnum.ORDINARY_MEMBERS.getKey());
			personnel.setIsPriorityOrder(FlagEnum.NO.getKey());
			personnel.setIsTop(FlagEnum.NO.getKey());
			personnel.setIsAutoReply(FlagEnum.NO.getKey());
			personnel.setDeleted(FlagEnum.NO.getKey());
			studioPersonnelSV.insert(personnel);
		}
		//加入服务项
		String serviceItem = servApp.getServiceItem();
		String prices = servApp.getPrice();
		String proportions = servApp.getProportion();
		if (serviceItem != null) {
			String[] split = serviceItem.split(",");
			String[] price = prices.split(",");
			String[] proportion = proportions.split(",");
			for (int i = 0; i < split.length; i++) {
				StudioPersonServiceEntity studioPersonService = new StudioPersonServiceEntity();
				studioPersonService.setStudioPersonId(personnel.getId());
				studioPersonService.setServiceId(split[i]);
				studioPersonService.setState(FlagEnum.IS.getKey());
				studioPersonService.setPrice(new BigDecimal(price[i]));
				studioPersonService.setProportion(new BigDecimal(proportion[i]));
				studioPersonServiceSV.insert(studioPersonService);
			}
		}
	}

	@Override
	public PageInfo<StudioRelatedFormVo> studioReviewList(Long loginId, String joinType, int pageNum, int pageSize) {
		PageHelper.startPage(pageNum, pageSize);
		List<StudioRelatedFormVo> data = mapper.studioReviewList(loginId, joinType);
		return new PageInfo<>(data);
	}
}
